home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C023A.ZIP / PART2 / ZLIB.C < prev    next >
Text File  |  1990-01-31  |  5KB  |  222 lines

  1. /*
  2.  * zlib - create library from all .obj files on current disk
  3.  *
  4.  * library consists of concatenation of all .obj files
  5.  * (except iolib.obj, which is not included)
  6.  * an index file to each module within the library is also created
  7.  *
  8.  * the index file starts with a list of all modules in the library
  9.  * together with the record number and offset of their starts
  10.  * (that is, the first record after the module name)
  11.  * this is follwed by a blank line
  12.  * next there is a list of symbols in the given module, each of
  13.  * which is followed by the number of the relevant module
  14.  * the number is positive for symbols defined in the module and
  15.  * negative for symbols referenced but not defined
  16.  *
  17.  * Bug reports, bug fixes and comments should be addressed to the author:
  18.  *
  19.  *    R M Yorston
  20.  *    1 Church Terrace
  21.  *    Lower Field Road
  22.  *    Reading
  23.  *    RG1 6AS
  24.  *
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30.  
  31. char *Index ;    /* table of undefined symbol (each up to 16 bytes) */
  32. int Undef ;        /* number of entries in undefined symbol table */
  33.  
  34. main(argc, argv)
  35. int argc, *argv ;
  36. {
  37.     int infile ;        /* input file descriptor */
  38.     int libfile ;        /* library file file descriptor */
  39.     int idxfile ;        /* index file file descriptor */
  40.     char record[257];    /* data record from .OBJ file */
  41.     int n ;                /* number of bytes in record */
  42.     char **files ;        /* pointer to input file names */
  43.     int rec ;            /* current record being written */
  44.     int offset ;        /* offset into record */
  45.     int i, j ;
  46.  
  47.     if ( argc != 2 ) {
  48.         fprintf(stderr, "usage: zlib libname");
  49.         exit() ;
  50.     }
  51.  
  52.     if ( strchr(argv[1], '.') != 0 ) {
  53.         fprintf(stderr, "library name should not include extension\n") ;
  54.         exit() ;
  55.     }
  56.  
  57.     /* open library file */
  58.     strcpy(record, argv[1]) ;
  59.     strcat(record, ".LIB") ;
  60.     if ( (libfile=fopen(record,"w")) == 0 ) {
  61.         fprintf(stderr, "unable to open library file");
  62.         exit();
  63.     }
  64.  
  65.     /* open index file */
  66.     strcpy(record, argv[1]) ;
  67.     strcat(record, ".IDX") ;
  68.     if ( (idxfile=fopen(record,"w")) == 0 ) {
  69.         fprintf(stderr, "unable to open index file") ;
  70.         exit() ;
  71.     }
  72.  
  73.     /* find .obj files */
  74.     if ( (files=wildcard("????????.OBJ")) == 0 ) {
  75.         fprintf(stderr, "no .OBJ files");
  76.         exit();
  77.     }
  78.  
  79.     /* process each file in list */
  80.     rec = offset = 0 ;
  81.     j = 0 ;
  82.     while ( files[j] ) {
  83.         /* do not include iolib.obj */
  84.         if ( strcmp(files[j], "IOLIB.OBJ") == 0 ) {
  85.             ++j ;
  86.             continue ;
  87.         }
  88.         /* try to open file */
  89.         if ( (infile=fopen(files[j],"r")) == 0 ) {
  90.             fprintf(stderr, "cannot open file: %s", files[j]) ;
  91.             exit();
  92.         }
  93.  
  94.         while ( (n=getrec(record,infile)) ) {
  95.             /* process each data record */
  96.             if ( record[0] == 1 && n == 2 ) {
  97.                 /* ignore null module names */
  98.                 continue ;
  99.             }
  100.             /* write data record to library */
  101.             putb(n+1,libfile);
  102.             for ( i=0; i<n; ++i ) {
  103.                 putb(record[i],libfile);
  104.             }
  105.             offset += n+1 ;
  106.             rec += offset/128 ;
  107.             offset %= 128 ;
  108.             if ( record[0] == 1 ) {
  109.                 /* name of module is not null, write it to index file */
  110.                 for ( i=2; i<n; ++i ) {
  111.                     putc(record[i], idxfile) ;
  112.                 }
  113.                 putc(' ', idxfile) ;
  114.                 /* write record/offset of given module */
  115.                 fprintf(idxfile, "%4d %3d\n", rec, offset) ;
  116.             }
  117.         }
  118.  
  119.         fclose(infile);
  120.         ++j ;
  121.     }
  122.  
  123.     /* write end of module record */
  124.     putb(2,libfile);
  125.     putb(0,libfile);
  126.  
  127.     /* write end of index marker */
  128.     fprintf(idxfile, "\n") ;
  129.  
  130.     fclose(libfile);
  131.  
  132.     /* now create index of functions within each module */
  133.  
  134.     /* open library file for read */
  135.     strcpy(record, argv[1]) ;
  136.     strcat(record, ".LIB") ;
  137.     if ( (libfile=fopen(record,"r")) == 0 ) {
  138.         fprintf(stderr, "unable to open file\n");
  139.         exit();
  140.     }
  141.  
  142.     /* allocate space for index of undefined symbols */
  143.     Index = alloc(4800) ;
  144.     /* process each module in library */
  145.  
  146.     i = -1 ;
  147.     Undef = 0 ;
  148.     while ( (n=getrec(record,libfile)) ) {
  149.         if ( record[0] == 1 ) {
  150.             /* new module, increase module number, clear Undef table */
  151.             ++i ;
  152.             Undef = 0 ;
  153.         }
  154.         if ( record[0] == 4 ) {
  155.             /* only deal with symbol records */
  156.             if ( (record[1] & 6) == 6 ) {
  157.                 /* global symbol defined here */
  158.                 record[n] = 0 ;
  159.                 fprintf(idxfile, "%s %d\n", &record[4], i+1) ;
  160.             }
  161.             else if ( (record[1] & 6) == 4 ) {
  162.                 record[n] = 0 ;
  163.                 /* global symbol not defined here */
  164.                 if ( !already(&record[4]) ) {
  165.                     /* only add to file if not there already */
  166.                     fprintf(idxfile, "%s %d\n", &record[4], -(i+1) ) ;
  167.                     /* add to table too */
  168.                     strcpy(&Index[Undef<<4],&record[4]) ;
  169.                     if ( ++Undef > 300 ) {
  170.                         fprintf(stderr,"symbol table overflow");
  171.                         exit() ;
  172.                     }
  173.                 }
  174.             }
  175.         }
  176.     }
  177.     fclose(libfile) ;
  178.     fclose(idxfile);
  179. }
  180.  
  181. /*
  182.  * fetch record from file
  183.  * return number of valid bytes, 0 for end of module
  184.  */
  185. getrec(ptr,fd)
  186. char *ptr ;
  187. int fd ;
  188. {
  189.     int i ;                /* count number of bytes from file */
  190.     int j ;                /* number of bytes returned in record */
  191.  
  192.     i = getb(fd) ;
  193.     if ( i == 2 || i == -1 ) {
  194.         return 0 ;
  195.     }
  196.     j = (--i) & 0xff ;
  197.     while ( i-- ) {
  198.         *ptr++ = getb(fd) ;
  199.     }
  200.     return j ;
  201. }
  202.  
  203. /*
  204.  * already -  check if symbol is already in undefined symbol table for this module
  205.  */
  206. already(s)
  207. char *s ;
  208. {
  209.     int i ;
  210.  
  211.     i = 0 ;
  212.     while ( i < Undef ) {
  213.         if ( strcmp(s,&Index[i<<4]) == 0 ) {
  214.             /* symbol is in table */
  215.             return 1 ;
  216.         }
  217.         ++i ;
  218.     }
  219.     /* symbol not found */
  220.     return 0 ;
  221. }
  222.